package com.zhanghe.study.study_scala.basic

/**
 * @author zh
 * @date 2021/5/9 13:16
 */
object TestMatch {
  def main(args: Array[String]): Unit = {
    val operator = '*'
    val num1 = 10
    val num2 = 2
    // => 后为执行的代码块，匹配到之后执行完代码块自动退出，不需要break
    // 如果没有匹配到，则执行case _ 默认操作
    val result = operator match {
      case '+' => num1 + num2
      case '-' => num1 - num2
      case '*' => num1 * num2
      case '/' => num1 / num2
      case '%' => num1 % num2
      case _ => throw new Exception("操作错误")
    }

    // 20
    println(result)


    // 条件守卫
    val operator1 = '+'
    val num3 = 3
    val num4 = 15
    val result1 = operator1 match {
      case '+' => num3 + num4
      // 由于不满足if条件num3 > num4，如果并没有执行该操作，继续向下匹配
      case '-' if num3 > num4 => num3 - num4
      case '*' => num3 * num4
      case '/' => num3 / num4
      case '%' => num3 % num4
      case _ => throw new Exception("操作错误")
    }

    // java.lang.Exception: 操作错误
    println(result1)

    // 类型匹配
    val list = List(1, "aaa", 3.0)
    for (item <- list) {
      item match {
        // 这里是将item赋值给a，再去判断类型的，如果后续用不到该变量，可以使用_
        case a: Int => println("Int类型")
        case b: String => println("String类型")
        case _ => println("这是什么类型，怎么出现在我的集合里了")
      }
    }

    val array = Array(Array(0), Array(0, 1, 2), Array(3, 4, 5))

    for (a <- array) {
      a match {
        case Array(0) => println(s"${a}该数组只有一个0")
        case Array(0, _*) => println(s"${a}该数组第一个元素为0")
        case Array(x, y, z) => println(s"${a}该数组第一个元素不为0，且有三个元素,分别为$x $y $z")
      }
    }


    val arrayList = Array(List(0), List(0, 1, 2), List(3, 4, 5))

    for (a <- arrayList) {
      a match {
        case List(0) => println(s"${a}该数组只有一个0")
        case List(0, _*) => println(s"${a}该数组第一个元素为0")
        case List(x, y, z) => println(s"${a}该数组第一个元素不为0，且有三个元素,分别为$x $y $z")
      }
    }

    // 对象匹配   根据unapply实现
    val stu1 = Student(1,"张三")
    val stu2 = Student(1,"李四")
    val stu3 = Student(2,"张三")

    val stuList = List(stu1,stu2,stu3)

    for(stu <- stuList){
      stu match {
        case Student(1) => println(s"相同的学生${stu.id}  ${stu.name}")
        case _ => println(s"不是相同的学生${stu.id}")
      }
    }

    // 样例类
    val tea1 = Teacher(1)
    val tea2 = Teacher(2)
    val tea3 = Teacher(1)
    val teaList = List(tea1,tea2,tea3)

    for(tea <- teaList){
      tea match {
        case Teacher(1) => println(s"相同的老师${tea.id} ")
        case _ => println(s"不是相同的老师${tea.id}")
      }
    }



  }

}

class Student(uid: Int) {
  var id: Int = uid
  var name: String = _

  def this(id: Int, name: String) = {
    this(id)
    this.name = name
  }
}

object Student {
  def unapply(stu: Student): Option[Int] = {
    println(stu.id + "-----"+stu.name)
    Some(stu.id)
  }

  def apply(id: Int) = {
    new Student(id)
  }

  def apply(id: Int, name: String) = {
    new Student(id, name)
  }
}

//样例类
case class Teacher(id :Int)
